package com.system.healthproject.interceptor;


import com.system.healthproject.annotation.RequireRole;
import com.system.healthproject.annotation.RequireToken;
import com.system.healthproject.exception.TokenException;
import com.system.healthproject.pojo.Role;
import com.system.healthproject.utils.JwtUtil;
import com.system.healthproject.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;

public class JwtInterceptor implements HandlerInterceptor {

    @Autowired
    RedisUtil redisUtil;


    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        //无论如何都放行，具体能不能操作还是在具体的操作中去判断
        //拦截器只是负责把请求头中包含token的令牌进行一个解析验证


        if (o instanceof HandlerMethod) {
            HandlerMethod method = (HandlerMethod) o;
            Class beanType = method.getBeanType();
            Method method1 = method.getMethod();
            if (
                    beanType.isAnnotationPresent(RequireRole.class)||
                    beanType.isAnnotationPresent(RequireToken.class)
                    || method1.isAnnotationPresent(RequireToken.class)
            ||method1.isAnnotationPresent(RequireRole.class)) {
                String token = httpServletRequest.getHeader("token");
                if (token != null && !"".equals(token)) {
                    //如果有包含有Authorization头信息，就对其进行解析
                    Map<String, Object> map = JwtUtil.validateToken(token);//在生成token的时候本身就是将角色作为关键字生成的
                    if (map == null) {
                        throw new TokenException("token不正确,请重新登录");
                    }
                    Map<String, Object> userInfo = (Map<String, Object>) redisUtil.get(token);
                    if(userInfo==null||userInfo.size()==0){
                        throw new TokenException("token失效,请重新登录");
                    }
                    //进行权限判断
                    if(
                            method1.isAnnotationPresent(RequireRole.class)
                                    ||
                                    beanType.isAnnotationPresent(RequireRole.class)){
                        RequireRole annotation=null;
                        if(method1.isAnnotationPresent(RequireRole.class)){
                            annotation = method1.getAnnotation(RequireRole.class);
                        }else if(beanType.isAnnotationPresent(RequireRole.class)){
                            annotation = (RequireRole)beanType.getAnnotation(RequireRole.class);
                        }

                        String value = annotation.value();
                        List<Role> roles = (List<Role>) userInfo.get("roles");
                        if(roles!=null&&roles.size()!=0){
                            Role role = roles.get(0);
                            String roleName = role.getRoleName();
                            if(roleName.equals(value)){
                                return true;
                            }
                        }
                        throw  new TokenException("权限验证错误,无法访问");
                    }
                } else {
                    throw new TokenException("未登录,请重新登录");
                }
            }

        }


        return true;//return true放行，return false不让往下走

    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}
